import React, { useEffect, useState, useMemo, useRef, useReducer } from 'react'
import { useSelector, useDispatch, TypedUseSelectorHook } from 'react-redux'
import { throttle } from 'lodash'
import { useLocation } from 'react-router-dom'
import qs from 'qs'

import { getFindUserResoureceFn, getRoleTypeOpts } from './util'
import {
  resourceMap,
  ResourceMap,
  ResourceMapKeys,
  defaultSubjectColor,
  defaultMapBackgroundColor,
} from './consts'
import type { RootState, AppDispatch } from '../redux/index'
// import { themeMap, mapThemeMap } from '@/pages/dataCenter/theme'

export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

export const useRefBounding = <T extends React.MutableRefObject<HTMLElement | null>>(eleRef: T) => {
  const [bounding, setBounding] = useState<DOMRect>({} as DOMRect)
  useEffect(() => {
    const start = () => {
      if (eleRef.current) {
        const bounding = eleRef.current.getBoundingClientRect()
        setBounding(bounding)
      }
    }
    start()
    const throttleStart = throttle(start, 100)
    window.addEventListener('resize', throttleStart)
    return () => {
      window.removeEventListener('resize', throttleStart)
    }
  }, [eleRef])
  return bounding
}

/**
 * UseTimingRequest 定时任务
 * @param fn 定时任务方法
 * @param param useEffect依赖，此依赖发生变更，定时任务自动更新
 * @param time 定时任务时间
 */
type UseTimingRequest = (
  fn: ((param: any) => () => void) | ((param: any) => void),
  param: any[],
  time?: number
) => void
export const useTimingRequest: UseTimingRequest = (fn, param, time = 300000) => {
  useEffect(() => {
    let cleanFn: any = null
    if (fn) {
      cleanFn = fn(param)
    }
    const timer = setInterval(() => {
      if (fn) {
        cleanFn = fn(param)
      }
    }, time)
    return () => {
      cleanFn && typeof cleanFn === 'function' && cleanFn()
      clearInterval(timer)
    }
  }, param)
}

export const useUserResources = <TSelected>(
  selector: (resourceMap: ResourceMap) => TSelected,
  resources?: UserResources
): TSelected => {
  const [app] = useAppSelector(state => [state.app])
  let userResources = app?.userResources || []
  if (resources) {
    userResources = resources
  }
  return useMemo(() => {
    const modulekeys = Object.keys(resourceMap) as ResourceMapKeys[]
    const findUserResourece = getFindUserResoureceFn(userResources)
    const result = {} as ResourceMap
    modulekeys.forEach(modulekey => {
      const obj = resourceMap[modulekey]
      result[modulekey] = Object.keys(obj).reduce((prev: any, key) => {
        prev[key] = findUserResourece(obj[key as keyof typeof obj])
        return prev
      }, {} as Record<keyof typeof obj, ReturnType<typeof findUserResourece>>)
    })
    return selector(result)
  }, [userResources])
}

type UseCallBackState<T> = (
  oldData: T
) => [newData: T, cb: (newData: T, cb: (data: T) => void) => void]

/**
 * 返回接收回调的 setState
 * const [state, setState] = useCallBackState('')
 * setState(newState, (newState) => {})
 */
export const useCallBackState: UseCallBackState<unknown> = oldData => {
  const cbRef = useRef<any>()
  const [data, setData] = useState(oldData)
  useEffect(() => {
    cbRef.current && cbRef.current(data)
  }, [data])
  return [
    data,
    (newData: any, cb: any) => {
      cbRef.current = cb
      setData(newData)
    },
  ]
}

/**
 * const query = useQuery()
 * const id = query.get('id')
 */
export const useQuery = () => {
  const { search } = useLocation()
  return React.useMemo(() => new URLSearchParams(search), [search])
}

/**
 * 手动更新组件
 */
export const useForceUpdate = () => {
  const forceUpdate = useReducer((bool: any) => !bool, true)[1]
  return forceUpdate
}

/**
 * 获取用户类型对应的下拉筛选项
 */
export const useRoleTypeOpts = () => {
  const [userInfo] = useAppSelector(state => [state.app.userInfo])
  return useMemo(() => {
    return getRoleTypeOpts(userInfo.roleType)
  }, [userInfo])
}

export const useDataCenterSearchParams = () => {
  return useMemo(() => {
    const searchStr = location.hash?.split('?')[1]
    if (searchStr) {
      try {
        const query = atob(decodeURIComponent(searchStr))
        return qs.parse(query)
      } catch (error) {
        return {}
      }
    }
    return {}
  }, [location.hash])
}

/**
 * 定时更新任务
 */
export const useTimerUpdate = (updater: () => any, dependency: any[], intervalTime = 20000) => {
  const timerRef = useRef<any>(null)
  useEffect(() => {
    let clear: any = updater()
    const interval = () => {
      timerRef.current && clearTimeout(timerRef.current)
      timerRef.current = setTimeout(() => {
        clear = updater?.()
        interval()
      }, intervalTime)
    }
    interval()
    return () => {
      clear && typeof clear === 'function' && clear()
      timerRef.current && clearTimeout(timerRef.current)
    }
  }, dependency)
}

/**
 * 当前实体数据中心主题色
 */
// export const useTheme = () => {
//   const [currentEntity] = useAppSelector(state => [state.app.currentEntity])
//   return useMemo(() => {
//     const mapBackgroundColor: string =
//       currentEntity?.mapBackgroundColor ?? defaultMapBackgroundColor
//     const subjectColor = currentEntity?.subjectColor ?? defaultSubjectColor
//     const dataCenterTheme = themeMap[subjectColor as keyof typeof themeMap]
//     const dataCenterMapTheme = mapThemeMap[mapBackgroundColor as keyof typeof mapThemeMap]
//     return { subjectColor, mapBackgroundColor, dataCenterTheme, dataCenterMapTheme }
//   }, [currentEntity])
// }
